﻿using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using Microsoft.Interop.Security.AzRoles;

namespace Authorization
{

    [DataContract(Name = "RoleDefinition", Namespace = "http://authorizationservices/v1")]
    public class RoleDefinition
    {
        private readonly IAzRoleDefinition _azRoleDefinition;

        #region Properties
        public Application Application { get; internal set; }

        [DataMember(Name = "Description", IsRequired = false)]
        public string Description { get; set; }

        [DataMember(Name = "Name", IsRequired = true)]
        public string Name { get; set; }

        [DataMember(Name = "Definition", IsRequired = false)]
        public Definition Definition { get; internal set; }
        /// <summary>
        ///  Name do <see cref="Scope"/> definido nesse <see cref="Role"/>
        /// </summary>
        [DataMember(Name = "ScopeName", IsRequired = false)]
        public string ScopeName
        {
            get;
            set;
        }
        #endregion


        internal RoleDefinition(Application application, IAzRoleDefinition azmanRoleDefinition, string scopeName)
        {
            this.Application = application;
            this.Description = azmanRoleDefinition.Description;
            this.Name = azmanRoleDefinition.Name;
            this._azRoleDefinition = azmanRoleDefinition;
            this.ScopeName = scopeName;
            Definition = scopeName != null ? Definition.Scope : Definition.Application;

        }

         ~RoleDefinition()
	{
            if (_azRoleDefinition != null)
                Marshal.FinalReleaseComObject(_azRoleDefinition);
        }


         public void RemoveRoleDefinition(string childRoleDefinitionName)
         {
             this._azRoleDefinition.DeleteRoleDefinition(childRoleDefinitionName);
         }

         public void AddRoleDefinition(string childRoleDefinitionName)
         {
             this._azRoleDefinition.AddRoleDefinition(childRoleDefinitionName);
         }
            
        public RoleAssignmentCollection GetRoleAssignments(string scopeNameToSearch, bool isRecursive)
        {
            return new RoleAssignmentCollection(this.Application, this._azRoleDefinition.RoleAssignments(scopeNameToSearch,isRecursive));
        }

         public string[] GetTaskNames()
         {
             var tasks = this._azRoleDefinition.Tasks as object[];

             if (tasks == null) return null;

             var taskNames = new List<string>(tasks.Length);

             foreach (var o in tasks)
             {
                 taskNames.Add((string)o);
             }

             return taskNames.ToArray();
         }

         public string[] GetOperationNames()
         {
             var operations = this._azRoleDefinition.Operations as object[];

             if (operations == null) return null;

             var operationNames = new List<string>(operations.Length);

             foreach (var o in operations)
             {
                 operationNames.Add((string)o);
             }

             return operationNames.ToArray();
         }

         public string[] GetRoleDefinitionNames()
         {
             var roleDefinitions = this._azRoleDefinition.RoleDefinitions;

             if (roleDefinitions == null) return null;

             var roleNames = new List<string>(roleDefinitions.Count);

             foreach (IAzRoleDefinition roleDefinition in roleDefinitions)
             {
                 roleNames.Add(roleDefinition.Name);
             }

             return roleNames.ToArray();
         }

        public  RoleDefinitionCollection GetRoleDefinitions()
        {
            return new RoleDefinitionCollection(this.Application, this._azRoleDefinition.RoleDefinitions,this.ScopeName);
        }

         public TaskCollection GetTasks()
         {
           return  Task.GetTasks(this.Application, this.ScopeName, GetTaskNames());
         }
       
         public OperationCollection GetOperations()
         {
             var operations = new OperationCollection();

             foreach (string strOperation in GetOperationNames())
             {
                 operations.Add(this.Application.GetOperation(strOperation));
             }

             return operations;
         }

         public void AddOperation(string operationName)
         {
            this._azRoleDefinition.AddOperation(operationName, null);
         }

         public void RemoveOperation(string operationName)
         {
             this._azRoleDefinition.DeleteOperation(operationName, null);
         }
         public void RemoveTask(string childTaskName)
         {
             this._azRoleDefinition.DeleteTask(childTaskName, null);
         }

         public void AddTask(string childTaskName)
         {
             this._azRoleDefinition.AddTask(childTaskName, null);
         }


         /// <summary>
         /// Submits the updates
         /// </summary>
         public void Save()
         {
             if (_azRoleDefinition == null) return;
             this._azRoleDefinition.Name = this.Name;
             this._azRoleDefinition.Description = this.Description;
             this._azRoleDefinition.Submit(0, null);
         }

         /// <summary>
         ///  Abort the updates
         /// </summary>
         public void Abort()
         {
             if (_azRoleDefinition == null) return;
             this._azRoleDefinition.Submit((int)tagAZ_PROP_CONSTANTS.AZ_SUBMIT_FLAG_ABORT,
                                          null);
             this.Name = this._azRoleDefinition.Name;
             this.Description = this._azRoleDefinition.Description;
         }
       
    }
}
